事實上,ActiveModel::Type
提供了 register
讓你可以把自定義的轉換器註冊到 Rails 裡去。
ActiveModel::Type.register :custom_type, CustomType
# 第一個輸入要註冊以供後續使用的 key(symbol),第二個輸入要註冊的轉換器 class。這邊延續上一篇使用的 CustomType
class MyClass2
# module 該 include 的就不再贅述 :P
attribute :json, :custom_type
end
# 上一篇的實驗重新試試看,假造一包 json string
input_json = '{"name":"Obama","age":64}'
form_object = MyClass2.new json: input_json
puts form_object.json
# 印出 {"name"=>"Obama", "age"=>64} ,轉型一樣成功!
值得注意的是,如果您使用 ActiveModel::Type.register
這方法把您的自訂轉換器註冊進去,這一行 registration 需要放在 Rails 專案的 config/initializers
裡面,以確保他一定會在其他 app 內的 class 被讀取到之前先註冊好。
因為 Rails 讀取檔案會有先後順序問題,再加上 lazy load
特性,如果沒有先在 Rails initialize 階段把轉換器註冊進去,您的 attribute 直接引用轉換器的 key,會因為找不到 type 的註冊資料而噴錯的!
class MyClass
# 假設我有在 app/ 內的某處檔案有註冊 another_type,但此時因為 lazy load 特性,那隻檔案尚未被 Rails 讀取
attribute :name, :another_type
end
ArgumentError (Unknown type :another_type)
# 就報錯了
在 Rails 的 ActiveModel::Type
裡面內建就已經註冊有很多的型態轉換器,除了可以用在 Active Model
以用來 parse 前端 form 傳來的 params 之外,也可以單獨引用來作當作 helper 來轉換型態,使用得當會相當的方便!
下一篇來介紹一下 boolean
。